/**
 * Copyright 2010 Victor Egea Hernando
 *
 * RockScript is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 *
 * RockScript is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with RockScript.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef PJIT_BLOCK_H_
#define PJIT_BLOCK_H_

#include "pjit.h"
#include <sstream>

namespace pjit{

class PAPER_API pjit_block {

public:
	// CONSTRUCTOR & DESTRUCTOR
	pjit_block( void );
	virtual ~pjit_block();

protected:
	// BLOCK AND POINTER
	uint32 _size;
	uint8 *_block;
	uint8 *_pointer;
	// ASM (SYMBOLIC) BUFFER
	bool _back_asm;
	std::stringstream _asms;

public:
	// INTERFACE WITH COMPILER
	void skip( uint32 bytes );
	void go_to( uint32 offset );
	void reserve( uint32 bytes );
	void push_1byte( uint8 data );
	void push_2bytes( uint16 data );
	void push_4bytes( uint32 data );
	void push_8bytes( uint64 data );
	// INTERFACE WITH ASM (SYMBOLIC) BUFFER
	bool back_asm( void ) const;
	std::ostream &asm_os( void );
	std::string asm_str( void ) const;
	void set_back_asm( bool block_asm );
	// GETTERS
	uint32 gap( void ) const;
	bool ready( void ) const;
	uint32 size( void ) const;
	uint32 offset( void ) const;
	// TYPES
	typedef void ( *__block_pntr )( void );
	// MAIN INTERFACE
	INLINE static void execute( pjit_block &block ){
		reinterpret_cast<__block_pntr>( block._block )();
	}

};

}; // namespace pjit

#endif // PJIT_BLOCK_H_
